/*
 * PhotonRTOS础光实时操作系统 -- CPU初始化相关文件
 *
 * Copyright (C) 2022, 2023 国科础石(重庆)软件有限公司
 *
 * 作者: Baoyou Xie <xiebaoyou@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#include <photon/init.h>
#include <asm/types.h>
#include <photon/cpu.h>
#include <photon/sched.h>

#include <asm/processor.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <autosar/internal.h>

#define CRL_APB_RST_LPD_TOP_OFFSET              0XFF5E023C
#define RPU0_TCM_CACHE_BASE			0xffe00000
#define RPU1_TCM_CACHE_BASE			0xffe90000
#define RPU1_ATCM_SIZE                          0x00002000

static void copy_initcode_to_rpu1(void)
{
	uint32_t *src;
	uint32_t *dest;

	for (src = (uint32_t *)RPU0_TCM_CACHE_BASE, dest = (uint32_t *)RPU1_TCM_CACHE_BASE;
		dest < (uint32_t *)(RPU1_TCM_CACHE_BASE + 0x00002000);) {
		*dest++ = *src++;
	}
}

static int32_t __r5_start_cpu(void)
{
	uintptr_t val = readl((volatile uint32_t)CRL_APB_RST_LPD_TOP_OFFSET);
	if (0 == (val & 0x3)) {
		pr_err("CRL_APB_RST_LPD_TOP_OFFSET ERR =  0x%x\n", val);
		return -1;
	}

	copy_initcode_to_rpu1();

	val = val & (~0x2);/*打开第二个CPU*/
	writel(val, (volatile uint32_t)CRL_APB_RST_LPD_TOP_OFFSET);
	return 0;
}

int32_t arch_launch_cpu(uint32_t cpu)
{
	return __r5_start_cpu();
}

void arch_start_slave(struct slave_cpu_data *slave_cpu_data)
{
	int32_t cpu = slave_cpu_data->cpu;
	smp_processor_id() = cpu;
	pr_debug("cpu=%d.\n", cpu);

#if MAX_CPUS > 1
	gic_secondary_init();
	arch_timer_secondary_init();
#endif

	mark_cpu_online(cpu, true);

	if (autosar_get_core_status(autosar_get_core_id()) != AUTOSAR_CORE) {
		pr_err("slave core start non autosar core\n");
	} else {
		/**
		 * 将控制权交给用户线程
		 */
		main();
	}

	enable_irq();

	pr_debug("从核心%d进入空闲任务运行\n", cpu);
	cpu_idle();

	BUG();
}
